<template>
	<view class="updateFace">
		<view class="updateFace-content ff-bg-fff ff-color-999 ff-font-14 ff-margin-12 ff-border-radius-10">
			<view class="ff-flex-between ff-align-items-one ff-padding-15 ff-border-bottom">
				<view class="updateFace-content-title">姓名</view>
				<view class="ff-color-222">{{ userInfo.username }}</view>
			</view>
			<view class="ff-flex-between ff-align-items-one ff-padding-15 ff-border-bottom">
				<view class="updateFace-content-title">身份证号</view>
				<view class="ff-color-222">{{ userInfo.userIdCard }}</view>
			</view>
		</view>
		<view class="ff-flex-between">
			<view class="updateFace-but"><u-button type="primary" shape="circle" @click="updateFaceClick">更新</u-button>
			</view>
		</view>
		<f-loading ref="loading" />
		<u-toast ref="uToast" />
		<u-modal :title="failTitle" v-model="failModal" :content-style="{ 'line-height': '1.5' }"
			:content="failContent" />
		<u-modal title="温馨提示" v-model="faceModal" :content-style="{ 'line-height': '1.5' }" @confirm="confirmFaceClick"
			:show-cancel-button="true" cancel-text="不做了" confirm-text="开始更新" content="请您确定身份证号码和姓名是您本人且正确无误，否则将不能更新！" />
		<u-modal title="录制人脸视频警告" :show-cancel-button="true" v-model="userWarningModal" @confirm="confirmUserWarning"
			:content="faceInfo.sessionCode" :content-style="{ 'line-height': '1.5' }" />
	</view>
</template>

<script>
	import config from '@/tools/config.js';
	export default {
		name: 'updateFace',
		data() {
			return {
				faceModal: false, // 人脸认证弹框显/隐
				userWarningModal: false, // 用户录制视频警告弹框
				failTitle: '', // 失败弹框的标题
				failContent: '', // 失败弹框的提示语
				failModal: false, // 失败弹框的显/隐
				userInfo: {}, // 用户信息
				// 人脸识别相关
				faceInfo: {
					faceState: false, // 人脸识别（通过true，不通过false）
					sessionId: '', // 百度sessionId
					accessToken: '', // 百度accesstoken
					sessionCode: '', // 用户需要大声读出数字
					videoPath: '', // 上传视频后返回的临时视频路径
					videoBase64: '', // 视频base64
					imageBase64: '' // 图片base64
				}
			};
		},
		onLoad() {
			this.getUserInfo(); // 获取当前管理员手机号
		},
		methods: {
			// 获取当前管理员手机号
			async getUserInfo() {
				this.$refs.loading.openLoading('加载中···'); // 打开loading动画
				const data = await this.$http.get({
					url: '/sys/user/info'
				});
				if (data.code == 200) {
					this.userInfo = data.data;
				}
				this.$refs.loading.closeLoading(); // 关闭loading动画
			},
			// 点击进行人脸认证-----------------
			updateFaceClick() {
				this.faceModal = true;
			},
			// 获取活体认证的数字验证码
			confirmFaceClick() {
				let that = this;
				that.$refs.loading.openLoading('开始比对公安人证信息···'); // 打开loading动画
				that.$http.post({
					url: `/face/baidubce/faceliveness/sessioncode/${that.userInfo.userIdCard}`
				}).then(res => {
					// console.log('获取活体认证的数字验证码---', res);
					if (res.code == 200 && res.data.code != '') {
						that.faceInfo.sessionId = res.data.sessionId;
						that.faceInfo.accessToken = res.data.accessToken;
						that.faceInfo.sessionCode = '人脸视频录制过程中，请大声的读出：' + res.data.code;
						that.userWarningModal = true; // 打开用户录制视频警告弹框
					} else {
						that.failTitle = '温馨提示'; // 失败的标题
						that.failContent = res.msg; // 失败的提示语
						that.failModal = true; // 失败弹框的显/隐
					}
					that.$refs.loading.closeLoading(); // 关闭loading动画
				});
			},
			// 警告用户录制视频
			confirmUserWarning() {
				let that = this;
				that.$refs.loading.openLoading(); // 打开loading动画
				uni.chooseVideo({
					count: 1,
					sourceType: ['camera'],
					camera: 'front',
					maxDuration: 5,
					compressed: true,
					success(res) {
						// console.log('返回视频文件的临时文件路径-----', res);
						that.faceInfo.videoPath = res.tempFilePath;
						// 获取全局唯一的文件管理器
						uni.getFileSystemManager().readFile({
							filePath: that.faceInfo.videoPath, // 选择视频返回的相对路径
							encoding: 'base64', //编码格式
							success: res => {
								//成功的回调
								that.faceInfo.videoBase64 = res.data;
								// console.log('图片转成base64-------', that.faceInfo.videoBase64);
								that.startVideoFaceProcess(); // 进行活体检测
							},
							fail: res => {
								that.$refs.loading.closeLoading(); // 关闭loading动画
								that.failTitle = '温馨提示'; // 失败的标题
								that.failContent = '出现错误，请及时联系管理员！'; // 失败的提示语
								that.failModal = true; // 失败弹框的显/隐
							}
						});
					},
					fail(res) {
						that.$refs.loading.closeLoading(); // 关闭loading动画
						that.failTitle = '温馨提示'; // 失败的标题
						that.failContent = '出现错误，请及时联系管理员！'; // 失败的提示语
						that.failModal = true; // 失败弹框的显/隐
					}
				});
			},
			// 活体视频认证(后台的接口)
			startVideoFaceProcess() {
				let that = this;
				let verifyVideo = {
					sessionId: that.faceInfo.sessionId,
					accessToken: that.faceInfo.accessToken,
					videoBase64: that.faceInfo.videoBase64, // base64 编码的视频数据
					lipIdentify: 'COMMON', // 辅助语音验证进行，用于判断验证码是否为当事人读出取值, COMMON代表使用唇语识别，STRICT代表使用唇语识别并使用更加严格的策略判断是否通过， OFF代表关闭唇语识别，默认OFF
					idcard: that.userInfo.userIdCard
				};
				// 请求视频认证检测（后台返回的视频数据）
				that.$refs.loading.openLoading('活体认证中，请稍候'); // 打开loading动画
				that.$http
					.post({
						url: '/face/baidubce/faceliveness/verify',
						data: verifyVideo
					})
					.then(res => {
						// console.log('获取活体认证检测返回得数据--------', res);
						// 活体认证结果 0：成功 1：失败
						if (res.code == 200 && res.data.errNo == 0) {
							that.faceInfo.imageBase64 = res.data.faceUrl; // 获取到后台返回的百度人脸图片地址
							that.faceInfo.accessToken = res.data.accessToken; // 更新百度accesstoken
							that.getBaiduTesting(); // 百度人脸库检测（检测是否是人脸）
						} else if (res.code == 200 && res.data.errNo == 1) {
							that.$refs.loading.closeLoading(); // 关闭loading动画
							that.failTitle = '温馨提示'; // 失败的标题
							that.failContent = res.data.errMsg; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
						} else {
							that.$refs.loading.closeLoading(); // 关闭loading动画
							that.failTitle = '温馨提示'; // 失败的标题
							that.failContent = res.msg; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
						}
					});
			},
			// 百度人脸库检测（检测是否是人脸）
			getBaiduTesting() {
				let that = this;
				that.$refs.loading.openLoading('人脸识别中，请稍候'); // 打开loading动画
				uni.request({
					url: 'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' + that.faceInfo
						.accessToken,
					method: 'POST',
					data: {
						image: that.faceInfo.imageBase64, // 图片信息(总数据大小应小于10M)，图片上传方式根据image_type来判断
						image_type: 'BASE64',
						face_fields: 'age,beauty,expression,face_shape,gender,glasses,landmark,landmark150,race,quality,eye_status,emotion,face_type',
						liveness_control: 'NORMAL' // 通过率
					},
					header: {
						'Content-Type': 'application/json'
					},
					success(res) {
						// console.log('人脸检测返回的数据-------', res);
						// Math.abs 函数返回指定数字 “x“ 的绝对值,列如 -1 ==> 1。
						if (
							res.data.error_msg == 'SUCCESS' &&
							res.data.result.face_num == 1 &&
							res.data.result.face_list[0].face_probability == 1 &&
							Math.abs(res.data.result.face_list[0].angle.pitch) < 20 &&
							Math.abs(res.data.result.face_list[0].angle.roll) < 20 &&
							Math.abs(res.data.result.face_list[0].angle.yaw) < 20 &&
							res.data.result.face_list[0].liveness.livemapscore > 0.393241
						) {
							that.getPublicTesting(); // 调取公安库检测的接口
						} else {
							that.$refs.loading.closeLoading(); // 关闭loading动画
							that.failTitle = '温馨提示'; // 失败的标题
							that.failContent = '视频不符合要求，请重拍！'; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
						}
					}
				});
			},
			// 公安库检测
			getPublicTesting() {
				let that = this;
				let identityInfo = {
					name: that.userInfo.username,
					idcard: that.userInfo.userIdCard,
					image: 'data:image/png;base64,' + that.faceInfo.imageBase64
				};
				// 公安系统接口认证
				that.$refs.loading.openLoading('身份认证中，请稍候'); // 打开loading动画
				that.$http
					.post({
						url: '/face/idcard',
						data: JSON.stringify(identityInfo)
					})
					.then(res => {
						// console.log('公安系统接口认证------', res);
						if (res.code == 200 && res.data.isvalid) {
							that.addBaiduFaceLibrary(); // 公安库认证成功，上传图片到百度人脸库
						} else {
							that.$refs.loading.closeLoading(); // 关闭loading动画
							that.failTitle = '温馨提示'; // 失败的标题
							that.failContent = '公安系统身份认证失败，请重新认证!'; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
						}
					});
			},
			// 上传人脸照片到人脸库
			addBaiduFaceLibrary() {
				// 新增人脸或者更新人脸到人脸库
				let that = this;
				that.$refs.loading.openLoading('人脸上传中，请稍候'); // 打开loading动画
				wx.request({
					url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=' + that.faceInfo
						.accessToken,
					method: 'POST',
					data: {
						image: that.faceInfo.imageBase64,
						image_type: 'BASE64',
						group_id: config.baidu_group_id, //自己建的用户组id
						user_id: config.baidu_userid_pre + that.userInfo.userIdCard //这里获取用户昵称
					},
					header: {
						'Content-Type': 'application/json'
					},
					success(res) {
						// console.log('新增百度人脸库返回的数据----', res);
						if (res.data.error_msg == 'SUCCESS') {
							that.$refs.loading.closeLoading(); // 关闭loading动画
							that.failTitle = '温馨提示';
							that.failContent = '认证成功!';
							that.failModal = true;
							that.faceInfo.faceState = true;
						} else if (res.data.error_code == '222210' || res.data.error_code == '223105') {
							// 222210：人脸库中用户下的人脸数目超过限制，223105：该人脸已存在
							that.upateBaiduFaceLibrary(); // 更新百度人脸库
						} else {
							that.$refs.loading.closeLoading(); // 关闭loading动画
							that.failTitle = '温馨提示'; // 失败的标题
							that.failContent = res.data.error_msg; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
						}
					}
				});
			},
			// 更新百度人脸库
			upateBaiduFaceLibrary() {
				let that = this;
				that.$refs.loading.openLoading('人脸更新中，请稍候'); // 打开loading动画
				wx.request({
					url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/update?access_token=' + that
						.faceInfo.accessToken,
					method: 'POST',
					data: {
						image: that.faceInfo.imageBase64,
						image_type: 'BASE64',
						group_id: config.baidu_group_id, //自己建的用户组id
						user_id: config.baidu_userid_pre + that.userInfo.userIdCard //这里获取用户昵称
					},
					header: {
						'Content-Type': 'application/json'
					},
					success(res) {
						// console.log('更新百度人脸库返回数据------', res);
						that.$refs.loading.closeLoading(); // 关闭loading动画
						if (res.data.error_msg == 'SUCCESS') {
							that.failTitle = '温馨提示'; // 失败的标题
							that.failContent = '人脸更新成功！'; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
							that.faceInfo.faceState = true;
						} else {
							that.failTitle = '温馨提示'; // 失败的标题
							that.failContent = res.data.error_msg; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
						}
					}
				});
			}
		}
	};
</script>

<style lang="scss" scoped>
	.updateFace {
		&-but {
			width: 90%;
			margin: 12% 5%;
		}

		.tips {
			position: absolute;
			right: 5%;
		}
	}
</style>